// MvcRouteUnitTester
// by Lee Dumond 
// twitter.com/LeeDumond

using System.Web;

namespace MvcRouteUnitTester
{
   using System;
   using System.Web.Mvc;
   using System.Web.Routing;

   /// <summary>
   /// An object which encapsulates routing information.
   /// </summary>
   public class RouteInfo
   {
      private readonly string action;
      private readonly RouteCollection applicationRoutes;
      private readonly string controller;
      private readonly RouteValueDictionary routeValueDictionary;

      internal RouteInfo(RouteCollection applicationRoutes, string action, string controller,
                         RouteValueDictionary routeValueDictionary)
      {
         this.action = action;
         this.controller = controller;
         this.applicationRoutes = applicationRoutes;
         this.routeValueDictionary = routeValueDictionary;
         HttpContext = TestUtility.GetHttpContext();
      }

      /// <summary>
      /// The mocked HTTP context for the test to be performed.
      /// </summary>
      public HttpContextBase HttpContext { get; set; }

      /// <summary>
      /// Asserts that the URL supplied to the method is the URL that is generated with the given routing information.
      /// </summary>
      /// <param name="expectedUrl">The URL that is expected to be generated.</param>
      /// <exception cref="ArgumentException">Thrown when the <paramref name="expectedUrl"/> argument is null, empty, or contains only whitespace.</exception>
      /// <exception cref="AssertionException">Thrown when the expected URL is not the URL that is generated with the given routing information.</exception>
      public void ShouldGenerateUrl(string expectedUrl)
      {
         if (string.IsNullOrWhiteSpace(expectedUrl))
         {
            throw new ArgumentException("Url cannot be null or empty.", "expectedUrl");
         }

         var context = new RequestContext(HttpContext, new RouteData());
         string generatedUrl = UrlHelper.GenerateUrl(null, action, controller, routeValueDictionary, applicationRoutes,
                                                     context, true);

         if (expectedUrl != generatedUrl)
         {
            throw new AssertionException(string.Format("URL mismatch. Expected: \"{0}\", but was: \"{1}\".", expectedUrl,
                                                       generatedUrl));
         }
      }

      /// <summary>
      /// Indicates whether the URL supplied to the method is the URL that is generated with the given routing information.
      /// </summary>
      /// <param name="expectedUrl">The URL that is expected to be generated.</param>
      /// <exception cref="ArgumentException">Thrown when the <paramref name="expectedUrl"/> argument is null, empty, or contains only whitespace.</exception>
      /// <returns>True if the expected URL is the URL that is generated with the given routing information; otherwise false.</returns>
      [Obsolete("Use native assertion method ShouldGenerateUrl instead.")]
      public bool GeneratesUrl(string expectedUrl)
      {
         try
         {
            ShouldGenerateUrl(expectedUrl);
            // Passed assertions without exception means it was a match.
            return true;
         }
         catch (AssertionException)
         {
            return false;
         }
      }
   }
}